package com.ndp.fb.rdb.mongo.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import com.ndp.fb.constant.MongoConstants;
import com.ndp.fb.mongo.api.PublishCacheMongoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by hunk.qin on 2016/1/21.
 */
@Service
public class PublishCacheMongoServiceImpl implements PublishCacheMongoService {

	private static Logger logger = LoggerFactory.getLogger(PublishCacheMongoServiceImpl.class);

    @Autowired
    private DB adResourceMongoDBClientPrimary;

    @Override
    public void save(String cacheJsonStr) {
        DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(cacheJsonStr);
        DBCollection dbCollection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
        dbCollection.save(dbObject,WriteConcern.JOURNALED);
    }

	@Override
	public void update(String batch_Id, String cacheJsonStr) {
		DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(cacheJsonStr);
		DBCollection dbCollection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId" ,batch_Id);
		dbCollection.update(query,dbObject,false,false,WriteConcern.JOURNALED);
	}

	@Override
    public String getCache(String batch_Id) {
		logger.info("get cahce by  batchId:{}",batch_Id);
		logger.info("query mongo db:{},address:{}",adResourceMongoDBClientPrimary.getName(),
				adResourceMongoDBClientPrimary.getMongo().getServerAddressList().get(0).toString());
        DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE );
        DBObject query = new BasicDBObject();
        query.put("cacheId" , batch_Id);
        DBObject dbObject = collection.findOne(query);
        if (dbObject == null) {
			logger.info("get cahce by  batchId:{},is null ,why???",batch_Id);
            return null;
        } else {
            return JSON.toJSONString(dbObject);
        }
    }

    @Override
    public void updateStatus(Long batchId, String key, int status, int type) {
    	 if(type==0){
    		 return;
    	 }
    	 DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE );
         DBObject query = new BasicDBObject();
         query.put("cacheId" , "batchId_"+batchId);
         DBObject update = new BasicDBObject();
         String mapName = getMapNameByType(type);
         update.put(mapName+"."+key+".status", status);
         collection.update(query, new BasicDBObject("$set", update));
         collection.update(query, new BasicDBObject("$set", update), false, false,WriteConcern.JOURNALED);
    }

    @Override
    public String findCacheBlockByType(Long batchId, int type) {
    	DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE );
        DBObject query = new BasicDBObject();
        query.put("cacheId" , "batchId_"+batchId);
        DBObject fields = new BasicDBObject();
        String mapName = getMapNameByType(type);
        fields.put(mapName, 1);
        DBObject dbObject = collection.findOne(query, fields);
        if(dbObject==null){
        	return null;
        }
        return JSONObject.toJSONString(dbObject.get(mapName));
    }

	@Override
	public void fillFbId(Long batchId, String key, String id, int type) {
		if (type == 0) {
			return;
		}
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId", "batchId_" + batchId);
		DBObject update = new BasicDBObject();
		String mapName = getMapNameByType(type);
		update.put(mapName + "." + key + "."+getFieldName(type), Long.valueOf(id));
		collection.update(query, new BasicDBObject("$set", update), false, false,WriteConcern.JOURNALED);
	}
	@Override
	public String findCacheBlockByTypeAndKey(Long batchId, int type, String key) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE );
        DBObject query = new BasicDBObject();
        String mapName = getMapNameByType(type);
        query.put("cacheId" , "batchId_"+batchId);
        DBObject fields = new BasicDBObject();
        fields.put(mapName+"."+key, 1);
        DBObject dbObject = collection.findOne(query, fields);
        if(dbObject==null){
        	return null;
        }
        return JSONObject.toJSONString(((DBObject)dbObject.get(mapName)).get(key));
	}

	@Override
	public Integer findAdCreativeSuccessByCacheId(Long batchId) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE );
		DBObject query = new BasicDBObject();
		query.put("cacheId" , "batchId_"+batchId);
		DBObject fields = new BasicDBObject();
		fields.put("adCreativeSucess", 1);
		DBObject dbObject = collection.findOne(query, fields);
		if(dbObject==null){
			return null;
		}
		return (Integer)dbObject.get("adCreativeSucess");
	}

	@Override
	public void updateAdCreativeSuccessByCacheId(Long batchId, Integer adCreativeSucess) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId", "batchId_" + batchId);
		DBObject update = new BasicDBObject();
		update.put("adCreativeSucess", adCreativeSucess);
		collection.update(query, new BasicDBObject("$set", update), false, false,WriteConcern.JOURNALED);
	}

	@Override
	public void updateCreativeVideoIdByKkey(String batch_Id, String creativeKey, String videoId) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId", batch_Id);
		DBObject update = new BasicDBObject();
		update.put("adCreativeLevelMap."+creativeKey+".objectStorySpec.videoData.videoId", videoId);
		collection.update(query, new BasicDBObject("$set", update), false, false,WriteConcern.JOURNALED);
	}

	@Override
	public String findDPAAttribute(Long batchId) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId", "batchId_" + batchId);
		DBObject fields = new BasicDBObject();
		fields.put("dpaAttribute", 1);
		DBObject dbObject = collection.findOne(query, fields);
		if(dbObject==null){
			return null;
		}
		Object dpaAttribute = dbObject.get("dpaAttribute");
		return dpaAttribute==null?"":JSONObject.toJSONString(dpaAttribute);
	}

	@Override
	public String findMarketTargetAttribute(Long batchId) {
		DBCollection collection = adResourceMongoDBClientPrimary.getCollection(MongoConstants.TABLE_NAME_PUBLISH_CACHE);
		DBObject query = new BasicDBObject();
		query.put("cacheId", "batchId_" + batchId);
		DBObject fields = new BasicDBObject();
		fields.put("marketTargetAttribute", 1);
		DBObject dbObject = collection.findOne(query, fields);
		if(dbObject==null){
			return null;
		}
		Object dpaAttribute = dbObject.get("marketTargetAttribute");
		return dpaAttribute==null?"":JSONObject.toJSONString(dpaAttribute);
	}
	private String getMapNameByType(int type){
		String name = "adCreativeLevelMap";
		switch (type) {
			case 0:
				name = "preSucceed";
				break;
			case 1:
				name = "adCreativeLevelMap";
				break;
			case 2:
				name = "adCampaignGroupLevelMap";
				break;
			case 3:
				name = "adSetLevelMap";
				break;
			case 4:
				name = "adGroupLevelMap";
				break;
			default:
				break;
		}
		return name;
	}

	private String getFieldName(int type){
		String name = "adCreativeId";
		switch (type) {
			case 1:
				name = "adCreativeId";
				break;
			case 2:
				name = "campaignGroupId";
				break;
			case 3:
				name = "adSetId";
				break;
			case 4:
				name = "adGroupId";
				break;
			default:
				break;
		}
		return name;
	}

}
